package org.alvin.i18n.newui;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import javax.script.ScriptException;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 学习型词典，中英文翻译
 */
public class I18nDictionary {

    //学习
    public static void learn() throws IOException {
        Path dir = Paths.get(System.getProperty("user.dir"), "learns");
        //
        Path dictionnaryPath = Paths.get(System.getProperty("user.dir"), "dict.json");
        if (!Files.exists(dictionnaryPath)) {
            Files.createFile(dictionnaryPath);
        }
        JSONObject dictionnary = restore(dictionnaryPath);
        LinkedList<Path> list = Lists.newLinkedList();
        list.add(dir.resolve("en"));

        while (!list.isEmpty()) {
            Path path = list.removeFirst();
            if (Files.isDirectory(path)) {
                list.addAll(Files.list(path).collect(Collectors.toList()));
            } else {
                System.out.println("学习文件：" + path);
                JSONObject jsonObject = getJSONByJsFile(path);
                // 中文对应
                String realDirPath = dir.toFile().getAbsolutePath();
                String nowPath = path.toFile().getAbsolutePath();
                String zhPath = nowPath.replace(realDirPath + File.separator + "en" + File.separator, realDirPath + File.separator + "zh" + File.separator);
                JSONObject zhJson = getJSONByJsFile(Paths.get(zhPath));

                //外层循环
                for (String key : jsonObject.keySet()) {
                    JSONObject dataJson = jsonObject.getJSONObject(key);
                    //循环数据
                    for (String dataKey : dataJson.keySet()) {
                        String value = dataJson.getString(dataKey);
                        putDictionary(dataKey, value, dictionnary, zhJson, key);
                    }
                }
            }
        }
        store(dictionnaryPath, dictionnary);
    }

    private static JSONObject getJSONByJsFile(Path path) throws IOException {
        byte[] buff1 = Files.readAllBytes(path);
        String content = new String(buff1, StandardCharsets.UTF_8);
        int index1 = content.lastIndexOf("export default {");
        int lastIndex = content.lastIndexOf("}");
        content = content.substring(index1 + "export default {".length() - 1, lastIndex + 1);
        //
        System.out.println("--读取内容路径：" + path);
        return JSONObject.parseObject(content);
    }

    //调整权重
    private static void putDictionary(String dataKey, String value, JSONObject dictionnary, JSONObject zhJson, String key) {
        JSONObject jsonObject = dictionnary.getJSONObject(dataKey);
        if (jsonObject == null) {
            jsonObject = new JSONObject();
            jsonObject.put("__chinese_key", getChineseData(zhJson, key, dataKey));
            dictionnary.put(dataKey, jsonObject);
        }
        Integer count = jsonObject.getInteger(value);
        if (count == null) {
            jsonObject.put(value, 1);
        } else {
            jsonObject.put(value, count + 1);
        }
    }

    private static String getChineseData(JSONObject zhJson, String key, String dataKey) {
        JSONObject zhDataJson = zhJson.getJSONObject(key);
        if (zhDataJson == null) {
            return null;
        }
        return zhDataJson.getString(dataKey);
    }

    /**
     * 还原
     *
     * @param dictionnaryPath
     * @return
     * @throws IOException
     */
    private static JSONObject restore(Path dictionnaryPath) throws IOException {
        byte[] buff = Files.readAllBytes(dictionnaryPath);
        if (buff.length == 0) {
            return new JSONObject();
        }
        return JSONObject.parseObject(new String(buff, Charset.forName("utf-8")));
    }

    /**
     * 写入
     *
     * @param dictionnaryPath
     * @param jsonObject
     * @throws IOException
     */
    private static void store(Path dictionnaryPath, JSONObject jsonObject) throws IOException {
        trimDict(jsonObject);
        String formatStr = JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
        Files.write(dictionnaryPath, formatStr.getBytes(StandardCharsets.UTF_8));
        System.out.println("输出结果：" + dictionnaryPath);
    }

    //获取
    public static String get(String key, String chinese) throws IOException {
        Path dictionnaryPath = Paths.get(System.getProperty("user.dir"), "dict.json");
        JSONObject dictionnary = restore(dictionnaryPath);
        JSONObject dataJson = dictionnary.getJSONObject(key);
        if (dataJson == null) {
            //根据中文查询
            for (String dictKey : dictionnary.keySet()) {
                JSONObject itemJson = dictionnary.getJSONObject(dictKey);
                String text = itemJson.getString("__chinese_key");
                if (chinese.equalsIgnoreCase(text)) {
                    dataJson = dictionnary.getJSONObject(dictKey);
                    return maxCountKey(dataJson);
                }
            }
            //自动翻译
            String value = sogoTranslate(chinese);
            dataJson = new JSONObject();
            dataJson.put("__chinese_key", chinese);
            dataJson.put(value, 1);
            dictionnary.put(key, dataJson);
            store(dictionnaryPath, dictionnary);
            return value;
        }
        return maxCountKey(dataJson);
    }

    private static String maxCountKey(JSONObject dataJson) {
        Collection<Object> values = dataJson.values();
        String value = values.stream().filter(item ->
                item.toString().matches("\\d+")
        ).map(item ->
                Integer.parseInt(item.toString())
        ).sorted(Comparator.reverseOrder()).findFirst().get().toString();
        for (Map.Entry<String, Object> entry : dataJson.entrySet()) {
            if (entry.getValue().toString().equals(value)) {
                return entry.getKey();
            }
        }
        return null;
    }

    //整理
    private static void trimDict(JSONObject jsonObject) {
        List<String> removeKeys = Lists.newArrayList();
        for (String key : jsonObject.keySet()) {
            JSONObject dataJson = jsonObject.getJSONObject(key);
            String chinese = dataJson.getString("__chinese_key");
            if (Strings.isNullOrEmpty(chinese)) {
                removeKeys.add(key);
                continue;
            }
            if (chinese.indexOf(" ") != -1 && chinese.indexOf("=") != -1) {
                removeKeys.add(key);
                System.out.println("删除内容：" + chinese);
                continue;
            }
            //根据中文 规则  长度 删除不需要的内容

            //固定内容去除
        }
        for (String key : removeKeys) {
            jsonObject.remove(key);
        }
        //统计频次
    }

    //翻译 但是不靠谱啊
    public static String sogoTranslate(String text) throws IOException {
        System.out.printf("翻译前：" + text);
        String url = "https://fanyi.sogou.com/text?keyword=%s&transfrom=auto&transto=en&model=general&fr=common_index_nav_pc";
        try {
            Document document = Jsoup.connect(String.format(url, URLEncoder.encode(text)))
                    .timeout(3000)
                    .execute().parse();
            Element element = document.getElementById("trans-result");
            if (element == null) {
                System.out.println("翻译不成功");
                return text;
            }
            try {
                String result = element.child(0).text();
                System.out.println("翻译结果：" + result);
                return result;
            } catch (Exception ex) {
                ex.printStackTrace();
                return text;
            }
        } catch (java.net.SocketTimeoutException e) {
            System.out.println(e);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            return sogoTranslate(text);
        }
    }

//    private static String baiduTranslate(String text) throws IOException {
//        System.out.println("改为百度：" + text);
//        String url = "https://fanyi.baidu.com/mtpe-individual/multimodal?query=%s&lang=zh2en";
//        url = String.format(url, text);
//        Document document = Jsoup.connect(String.format(url, URLEncoder.encode(text))).get();
//        try {
//            System.out.println(document.toString());
//            Element element = document.getElementsByClass("nbyIWSn1").get(0);
//            String result = element.child(0).text();
//            System.out.printf("翻译结果：" + result);
//            return result;
//        } catch (Exception ex) {
//            ex.printStackTrace();
//            return text;
//        }
//    }

    //执行一下
    public static void main(String[] args) throws IOException, ScriptException {
//        sogoTranslate("你好");
        learn();
    }
}
